package com.msblearn.C_004;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 线程安全的类：
 * java.util.concurrent.atomic
 * AtomcXXX类本身方法都是原子性的。但不能保证多个方法连续调用都是原子性的。
 * 使用CAS（Compare And Set）保证多线程的情况下是安全的
 * CAS三个值：V，expected,newValue
 *      V:原来的值，
 *      expected：期望值，可以理解为现在这个最新值
 *      newValue:需要修改的值。
 * ABA问题：主要是说在进行CAS操作的时候，如果有其他的线程把原来的1变为了2，另外的线程又把2变为了1，这时候
 * 值还是和原来一样，这就是ABA问题。（加入版本号：version）
 * ABA如果基础数据类型无所谓（不会有影响），引用类型，你的女朋友跟你复合，中间经历了其他男人，这个女人已经不是你原来的女朋友了
 *
 *
 * UnSafe类：只能通过反射去使用。其他方法获取不到。Atomic下的类都是通过Unsafe类。（11.0可以直接用。单例。）
 * 直接操作内存。等同与C/C++的内存操作。
 *
 * CAS(乐观锁)相关操作：
 * weakCompareAndSetObject
 * 弱指针：GC时效率比较高。
 */
public class T001_AtomicInteger {
    AtomicInteger count = new AtomicInteger(0);

    private void m() {
        for (int i = 0; i < 10000; i++) {
            //count++
            count.incrementAndGet();
        }
    }

    public static void main(String[] args) {
        T001_AtomicInteger atomicInteger = new T001_AtomicInteger();
        //创建线程list
        List<Thread> threads = new ArrayList<>();
        for (int i=0;i<10;i++){
            threads.add(new Thread(atomicInteger::m,"线程："+i));
        }

        //启动线程
        threads.forEach((o)->o.start());

        threads.forEach((o)->{
            try {
                o.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println(atomicInteger.count);
    }
}


